home *** CD-ROM | disk | FTP | other *** search
/ Merciful 1 / Merciful - Disc 1.iso / software / i / image_fx / imagefxv1.5c.dms / imagefxv1.5c.adf / MAGIC / src / mdemo.c < prev    next >
C/C++ Source or Header  |  1993-07-15  |  16KB  |  622 lines

  1. /*
  2.  * MAGIC Image Tester - creates a small public MAGIC image with
  3.  *    a teeny tiny interface.
  4.  *
  5.  * Written by Thomas Krehbiel
  6.  *
  7.  * (This requires 2.0, BTW.)
  8.  *
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <libraries/dos.h>
  14. #include <intuition/intuition.h>
  15. #include <libraries/gadtools.h>
  16. #include <clib/exec_protos.h>
  17. #include <clib/alib_protos.h>
  18. #include <clib/dos_protos.h>
  19. #include <clib/intuition_protos.h>
  20. #include <clib/graphics_protos.h>
  21. #include <clib/gadtools_protos.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdarg.h>
  25. #include <stdio.h>
  26.  
  27. #include <magic/magic.h>
  28. #include <magic/magic_protos.h>
  29. #include <magic/magic_pragmas.h>
  30.  
  31. struct Library *IntuitionBase;
  32. struct Library *GfxBase;
  33. struct Library *GadToolsBase;
  34.  
  35. struct MagicBase *MagicBase;
  36.  
  37. UBYTE *planes[4] = { NULL, NULL, NULL, NULL };
  38. struct MagicImage *mi;
  39. struct MagicHandle *mh;
  40. struct MsgPort *hostport;
  41.  
  42.  
  43. void message (char *, ...);
  44.  
  45.  
  46. #define WIDTH     320
  47. #define HEIGHT    200
  48. #define DEPTH     3        /* color */
  49.  
  50. short real_width, real_height;
  51.  
  52. BOOL alloc_planes (UBYTE **planes, int depth)
  53. {
  54.    int i;
  55.  
  56.    for (i = 0; i < depth; i++) planes[i] = NULL;
  57.  
  58.    for (i = 0; i < depth; i++) {
  59.       if (!(planes[i] = AllocMem(WIDTH * HEIGHT, MEMF_CLEAR | MEMF_PUBLIC))) {
  60.          return(FALSE);
  61.       }
  62.    }
  63.  
  64.    /* gradient from black to light violet */
  65.    for (i = 0; i < HEIGHT; i++) {
  66.       memset(planes[0] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
  67.       memset(planes[1] + (WIDTH * i), i * 127 / (HEIGHT-1), WIDTH);
  68.       memset(planes[2] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
  69.    }
  70.  
  71.    real_width = WIDTH;
  72.    real_height = HEIGHT;
  73.  
  74.    return(TRUE);
  75. }
  76.  
  77. void free_planes (UBYTE **planes, int depth)
  78. {
  79.    int i;
  80.  
  81.    for (i = 0; i < depth; i++) {
  82.       if (planes[i]) {
  83.          FreeMem(planes[i], real_width * real_height);
  84.          planes[i] = NULL;
  85.       }
  86.    }
  87. }
  88.  
  89.  
  90. static
  91. BOOL __saveds PutData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
  92. {
  93.    UBYTE *tagdata;
  94.    LONG byte;
  95.    UBYTE *ptr;
  96.    int i;
  97.  
  98.    while (*tags != TAG_END) {
  99.       tagdata = (UBYTE *)tags[1];
  100.       switch (*tags) {
  101.          case TAG_IGNORE :
  102.             break;
  103.          case GMI_Red :
  104.             CopyMem(tagdata, planes[0] + (offset * WIDTH), WIDTH * rows);
  105.             break;
  106.          case GMI_Green :
  107.             CopyMem(tagdata, planes[1] + (offset * WIDTH), WIDTH * rows);
  108.             break;
  109.          case GMI_Blue :
  110.             CopyMem(tagdata, planes[2] + (offset * WIDTH), WIDTH * rows);
  111.             break;
  112.          case GMI_RGB :
  113.             byte = offset * WIDTH;
  114.             ptr = (UBYTE *)tagdata;
  115.             for (i = 0; i < WIDTH; i++) {
  116.                planes[0][byte] = *ptr++;
  117.                planes[1][byte] = *ptr++;
  118.                planes[2][byte++] = *ptr++;
  119.             }
  120.             break;
  121.          case GMI_ARGB :
  122.             byte = offset * WIDTH;
  123.             ptr = (UBYTE *)tagdata;
  124.             for (i = 0; i < WIDTH; i++) {
  125.                ptr++;   /* skip alpha */
  126.                planes[0][byte] = *ptr++;
  127.                planes[1][byte] = *ptr++;
  128.                planes[2][byte++] = *ptr++;
  129.             }
  130.             break;
  131.          default :
  132.             break;
  133.       }
  134.       tags += 2;
  135.    }
  136.    return(TRUE);
  137. }
  138.  
  139. static
  140. BOOL __saveds GetData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
  141. {
  142.    UBYTE *tagdata;
  143.    LONG byte;
  144.    UBYTE *ptr;
  145.    int i;
  146.  
  147.    while (*tags != TAG_END) {
  148.       tagdata = (UBYTE *)tags[1];
  149.       switch (*tags) {
  150.          case TAG_IGNORE :
  151.             break;
  152.          case GMI_Red :
  153.             CopyMem(planes[0] + (offset * WIDTH), tagdata, WIDTH * rows);
  154.             break;
  155.          case GMI_Green :
  156.             CopyMem(planes[1] + (offset * WIDTH), tagdata, WIDTH * rows);
  157.             break;
  158.          case GMI_Blue :
  159.             CopyMem(planes[2] + (offset * WIDTH), tagdata, WIDTH * rows);
  160.             break;
  161.          case GMI_RGB :
  162.             byte = offset * WIDTH;
  163.             ptr = (UBYTE *)tagdata;
  164.             for (i = 0; i < WIDTH; i++) {
  165.                *ptr++ = planes[0][byte];
  166.                *ptr++ = planes[1][byte];
  167.                *ptr++ = planes[2][byte++];
  168.             }
  169.             break;
  170.          case GMI_ARGB :
  171.             byte = offset * WIDTH;
  172.             ptr = (UBYTE *)tagdata;
  173.             for (i = 0; i < WIDTH; i++) {
  174.                *ptr++ = 255;
  175.                *ptr++ = planes[0][byte];
  176.                *ptr++ = planes[1][byte];
  177.                *ptr++ = planes[2][byte++];
  178.             }
  179.             break;
  180.          default :
  181.             break;
  182.       }
  183.       tags += 2;
  184.    }
  185.    return(TRUE);
  186. }
  187.  
  188. BOOL init_magic (void)
  189. {
  190.    if (!(MagicBase = (struct MagicBase *)OpenLibrary(MAGIC_NAME, 34)))
  191.       return(FALSE);
  192.  
  193.    return(TRUE);
  194. }
  195.  
  196. void close_magic (void)
  197. {
  198.    if (mh) {
  199.       CloseMagicImage(mh);
  200.       mh = NULL;
  201.    }
  202.    if (mi) {
  203.       while (!RemMagicImage(mi)) {
  204.          message("Image in use!");
  205.          Delay(50);
  206.       }
  207.       FreeMagicImage(mi);
  208.       free_planes(planes, DEPTH);
  209.       mi = NULL;
  210.    }
  211. }
  212.  
  213. void cleanup_magic (void)
  214. {
  215.    close_magic();
  216.    CloseLibrary((struct Library *)MagicBase);
  217. }
  218.  
  219. void new_magic (void)
  220. {
  221.    close_magic();
  222.  
  223.    if (alloc_planes(planes, DEPTH)) {
  224.       if (mi = AllocMagicImage(AMI_Width, WIDTH,
  225.                                   AMI_Height, HEIGHT,
  226.                                   AMI_Depth, DEPTH,
  227.                                   AMI_Red, planes[0],
  228.                                   AMI_Green, planes[1],
  229.                                   AMI_Blue, planes[2],
  230.                                   AMI_GetDataCode, GetData,
  231.                                   AMI_PutDataCode, PutData,
  232.                                   AMI_OwnerName, "MagicDemo",
  233.                                   TAG_END)) {
  234.          if (AddMagicImage(mi)) {
  235.             /*
  236.              * Even the owner of an image must open it!  Remember to use
  237.              * OMI_OwnerPort instead of OMI_MsgPort.
  238.              */
  239.             if (mh = OpenMagicImage(mi, NULL, OMI_OwnerPort, hostport, TAG_END)) {
  240.                message("Magic image created.");
  241.                return;
  242.             }
  243.             RemMagicImage(mi);
  244.          }
  245.          FreeMagicImage(mi);
  246.       }
  247.       free_planes(planes, DEPTH);
  248.    }
  249.  
  250.    mi = NULL;
  251.    mh = NULL;
  252. }
  253.  
  254. struct NewMenu newMenus[] = {
  255.    { NM_TITLE, "Project",        NULL, 0, 0, 0 },
  256.    { NM_ITEM,  "New",            "N",  0, 0, 0 },
  257.    { NM_ITEM,  "Open...",        "O",  0, 0, 0 },
  258.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  259.    { NM_ITEM,  "Manipulate",     "M",  0, 0, 0 },
  260.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  261.    { NM_ITEM,  "Cycle",          "C",  0, 0, 0 },
  262.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  263.    { NM_ITEM,  "Quit",           "Q",  0, 0, 0 },
  264.    { NM_END }
  265. };
  266.  
  267. struct Window *win;
  268. struct Menu *menus;
  269. APTR vi;
  270.  
  271. BOOL init_gui (void)
  272. {
  273.    struct Screen *scr;
  274.  
  275.    IntuitionBase = OpenLibrary("intuition.library", 37);
  276.    GfxBase = OpenLibrary("graphics.library", 37);
  277.    GadToolsBase = OpenLibrary("gadtools.library", 37);
  278.    /* (yes, I know, but it's just a demo) */
  279.  
  280.    scr = LockPubScreen(NULL);
  281.    if (scr == NULL) return(FALSE);
  282.  
  283.    if (!(win = OpenWindowTags(NULL,
  284.                               WA_Title, "MAGIC Testerosa",
  285.                               WA_InnerWidth, 200,
  286.                               WA_Height, 115 + scr->WBorTop + scr->Font->ta_YSize + 1 + scr->WBorBottom + scr->RastPort.TxHeight + 2,
  287.                               WA_Left, 20,
  288.                               WA_Top, 20,
  289.                               WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR |
  290.                                           WFLG_DEPTHGADGET |
  291.                                           WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH |
  292.                                           WFLG_ACTIVATE,
  293.                               WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
  294.                               WA_NewLookMenus, TRUE,
  295.                               TAG_END))) goto err1;
  296.  
  297.    menus = CreateMenus(newMenus, TAG_END);
  298.    if (menus == NULL) goto err2;
  299.  
  300.    vi = GetVisualInfo(scr, TAG_END);
  301.    if (vi == NULL) goto err3;
  302.  
  303.    LayoutMenus(menus, vi, GTMN_NewLookMenus, TRUE, TAG_END);
  304.  
  305.    SetMenuStrip(win, menus);
  306.  
  307.    UnlockPubScreen(NULL, scr);
  308.  
  309.    return(TRUE);
  310.  
  311. err3:
  312.    FreeMenus(menus);
  313. err2:
  314.    CloseWindow(win);
  315. err1:
  316.    UnlockPubScreen(NULL, scr);
  317.    return(FALSE);
  318. }
  319.  
  320. void cleanup_gui (void)
  321. {
  322.    ClearMenuStrip(win);
  323.    FreeVisualInfo(vi);
  324.    FreeMenus(menus);
  325.    CloseWindow(win);
  326.    CloseLibrary(GadToolsBase);
  327.    CloseLibrary(GfxBase);
  328.    CloseLibrary(IntuitionBase);
  329. }
  330.  
  331. /* 4x4 dispersed dot ordered dither pattern. */
  332. static
  333. UBYTE dith[4][4] = {
  334.     1, 15,  2, 12,
  335.     9,  5, 10,  7,
  336.     3, 13,  0, 14,
  337.    11,  7,  8,  4
  338. };
  339.  
  340. void redraw (void)
  341. {
  342.    UBYTE *outpix;
  343.    UBYTE *rgb;
  344.    int w, h, le, te;
  345.    struct MagicImage *mi;
  346.    struct RastPort temprp;
  347.    struct BitMap tempbm;
  348.    int i, j, x, y;
  349.    short v;
  350.  
  351.    w = win->Width - win->BorderLeft - win->BorderRight - 4;
  352.    h = win->Height - win->BorderTop - win->BorderBottom - 2 - win->RPort->TxHeight - 2;
  353.    le = win->BorderLeft + 2;
  354.    te = win->BorderTop + win->RPort->TxHeight + 3;
  355.  
  356.    if (!mh) {
  357.       SetAPen(win->RPort, 0);
  358.       RectFill(win->RPort, le, te, le + w - 1, te + h - 1);
  359.       return;
  360.    }
  361.  
  362.    mi = mh->Object;
  363.  
  364.    outpix = AllocMem(((w+15)>>4)<<4, MEMF_CLEAR);
  365.    if (outpix == NULL) return;
  366.  
  367.    rgb = AllocMem(mi->Width * 3, MEMF_CLEAR);
  368.    if (rgb == NULL) return;
  369.  
  370.    InitRastPort(&temprp);
  371.    InitBitMap(&tempbm, win->RPort->BitMap->Depth, w, 1);
  372.    temprp.BitMap = &tempbm;
  373.    for (i = 0; i < tempbm.Depth; i++) {
  374.       tempbm.Planes[i] = AllocRaster(w, 1);
  375.       /* ick */
  376.    }
  377.  
  378.    for (j = 0; j < h; j++) {
  379.  
  380.       y = j * (mi->Height-1) / (h-1);
  381.       GetMagicImageData(mh, y, 1, GMI_RGB, rgb, TAG_END);
  382.  
  383.       for (i = 0; i < w; i++) {
  384.          x = (i * (mi->Width-1) / (w-1)) * 3;
  385.          v = ((rgb[x] + rgb[x+1] + rgb[x+2]) / 3) >> 4;
  386.          if (v > dith[j&3][i&3]) outpix[i] = 2;
  387.          else                    outpix[i] = 1;
  388.       }
  389.  
  390.       WritePixelLine8(win->RPort, le, te + j, w, outpix, &temprp);
  391.  
  392.    }
  393.  
  394.    for (i = 0; i < tempbm.Depth; i++) {
  395.       FreeRaster(tempbm.Planes[i], w, 1);
  396.    }
  397.  
  398.    FreeMem(rgb, mi->Width * 3);
  399.    FreeMem(outpix, ((w+15)>>4)<<4);
  400. }
  401.  
  402. struct MagicImage *pick_magic (void)
  403. {
  404.    struct MagicImage *m = NULL;
  405.  
  406.  
  407.    m = PickMagicImage(NULL,
  408.          PMI_ExcludeOwner, "MagicDemo",
  409.          PMI_ShowSize, TRUE,
  410.          PMI_ShowOwner, TRUE,
  411.          TAG_END);
  412.  
  413.    if (m) {
  414.       close_magic();
  415.  
  416.       if (mh = OpenMagicImage(m, NULL, OMI_MsgPort, hostport, TAG_END)) {
  417.          message("Magic Image opened.");
  418.       }
  419.    }
  420.  
  421.    return(m);
  422. }
  423.  
  424. void message (char *txt, ...)
  425. {
  426.    struct RastPort *rp = win->RPort;
  427.    char buf[80];
  428.    va_list va;
  429.  
  430.    va_start(va, txt);
  431.    vsprintf(buf, txt, va);
  432.    va_end(va);
  433.  
  434.    SetAPen(rp, 0);
  435.    SetDrMd(rp, JAM1);
  436.    RectFill(rp,
  437.       win->BorderLeft,
  438.       win->BorderTop,
  439.       win->Width - win->BorderRight - 1,
  440.       win->BorderTop + rp->TxHeight);
  441.  
  442.    SetAPen(rp, 1);
  443.    SetDrMd(rp, JAM1);
  444.    Move(rp, win->BorderLeft + 2, win->BorderTop + rp->TxBaseline + 1);
  445.    Text(rp, buf, strlen(buf));
  446. }
  447.  
  448.  
  449. void __regargs negative (UBYTE *data, int width)
  450. {
  451.    while (width--) {
  452.       *data = 255 - *data;
  453.       data++;
  454.    }
  455. }
  456.  
  457. /* do something interesting to the image buffer.  yeah, right */
  458.  
  459. void manipulate (void)
  460. {
  461.    struct MagicImage *mi;
  462.    UBYTE *buf;
  463.    int j, p;
  464.    LONG tag[3] = { GMI_Red, GMI_Green, GMI_Blue };
  465.  
  466.    if (mh) {
  467.       if (!AttemptLockMagicImage(mh, LMI_Write)) {
  468.          message("Image is locked.");
  469.          return;
  470.       }
  471.       mi = mh->Object;
  472.       if (buf = AllocMem(mi->Width, MEMF_CLEAR)) {
  473.  
  474.          message("Processing...");
  475.          if (!mi) SaveMagicImage(mh, 0, 0, mi->Width, mi->Height);
  476.          for (j = 0; j < mi->Height; j++) {
  477.             for (p = 0; p < mi->Depth; p++) {
  478.                GetMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
  479.                negative(buf, mi->Width);
  480.                PutMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
  481.             }
  482.          }
  483.          RedrawMagicImage(mh, 0, 0, mi->Width, mi->Height);
  484.          message("Image manipulated.");
  485.  
  486.          FreeMem(buf, mi->Width);
  487.       }
  488.  
  489.       UnlockMagicImage(mh);
  490.    }
  491. }
  492.  
  493. void halve (void)
  494. {
  495. #if 0
  496.    UBYTE *newplane;
  497.    int neww, newh;
  498.  
  499.    if (mi) {
  500.       neww = real_width / 2;
  501.       newh = real_height / 2;
  502.       for (p = 0; p < 3; p++) {
  503.          newplane = AllocMem(neww * newh, MEMF_CLEAR);
  504.          if (newplane == NULL) break;  /* crash city */
  505.          /* FINISH THIS! */
  506.       }
  507.    }
  508.    else {
  509.       message("Can't resize foreign images.");
  510.    }
  511. #endif
  512. }
  513.  
  514.  
  515. void event_loop (void)
  516. {
  517.    struct IntuiMessage *msg;
  518.    struct MagicMessage *mmsg;
  519.    ULONG wsig, hsig, sigs;
  520.    BOOL quit = FALSE;
  521.    int oldpri;
  522.  
  523.    message("Standing by...");
  524.  
  525.    wsig = 1 << win->UserPort->mp_SigBit;
  526.    hsig = 1 << hostport->mp_SigBit;
  527.  
  528.    while (!quit) {
  529.  
  530.       sigs = Wait(wsig | hsig);
  531.  
  532.       if (sigs & wsig) {
  533.          while (msg = (struct IntuiMessage *)GetMsg(win->UserPort)) {
  534.             switch(msg->Class) {
  535.                case IDCMP_CLOSEWINDOW :
  536.                   quit = TRUE;
  537.                   break;
  538.                case IDCMP_MENUPICK :
  539.                   switch(ITEMNUM(msg->Code)) {
  540.                      case 0 : new_magic(); redraw(); break;
  541.                      case 1 : pick_magic(); redraw(); break;
  542.                      case 3 : manipulate(); redraw(); break;
  543.                      case 5 : if (mh) CycleMagicImage(mh); break;
  544.                      case 7 : quit = TRUE; break;
  545.                      default: break;
  546.                   }
  547.                   break;
  548.                default :
  549.                   break;
  550.             }
  551.             ReplyMsg((struct Message *)msg);
  552.          }
  553.       }
  554.  
  555.       if (sigs & hsig) {
  556.          while (mmsg = (struct MagicMessage *)GetMsg(hostport)) {
  557.             mmsg->Result = 0;
  558.             switch(mmsg->Action) {
  559.                case MMSG_UPDATE :
  560.                   message("Update");
  561.                   break;
  562.                case MMSG_REDRAW :
  563.                   message("Redraw %ld %ld %ld %ld",
  564.                      mmsg->Args[0], mmsg->Args[1], mmsg->Args[2], mmsg->Args[3]);
  565.                   oldpri = SetTaskPri(FindTask(NULL), -1);
  566.                   redraw();
  567.                   SetTaskPri(FindTask(NULL), oldpri);
  568.                   break;
  569.                case MMSG_TOFRONT :
  570.                   message("To Front");
  571.                   ScreenToFront(win->WScreen);
  572.                   WindowToFront(win);
  573.                   ActivateWindow(win);
  574.                   break;
  575.                case MMSG_SAVEUNDO :
  576.                   message("Save Undo");
  577.                   break;
  578.                case MMSG_RESTOREUNDO :
  579.                   message("Restore Undo");
  580.                   break;
  581.                case MMSG_CLOSE :
  582.                   message("Hit The Road");
  583.                   close_magic();
  584.                   redraw();
  585.                   break;
  586.                default :
  587.                   mmsg->Result = -1;
  588.                   break;
  589.             }
  590.             ReplyMsg((struct Message *)mmsg);
  591.          }
  592.       }
  593.  
  594.       if (quit) {
  595.          if (mi && mi->OpenCount > 1) {
  596.             message("No way - image in use.");
  597.             quit = FALSE;
  598.          }
  599.       }
  600.  
  601.    }
  602. }
  603.  
  604.  
  605. void main (int argc, char **argv)
  606. {
  607.    struct Task *task = FindTask(NULL);
  608.  
  609.    task->tc_Node.ln_Name = "Magic Demo";
  610.  
  611.    if (hostport = CreatePort(NULL, 0)) {
  612.       if (init_gui()) {
  613.          if (init_magic()) {
  614.             event_loop();
  615.             cleanup_magic();
  616.          }
  617.          cleanup_gui();
  618.       }
  619.       DeletePort(hostport);
  620.    }
  621. }
  622.